鐵人賽已經倒數兩天了!最後想教教大家一個有趣且進階的應用,就是部署靜態網頁!
大家相信下面這張網頁圖是用 GAS + google sheet 架出來的嗎~~
讓我們一步一步拆解 GAS 部署網頁的過程吧!
讓我們先用一個最簡單的 hello world 按鈕作為範例~
GAS 架網頁只需要兩個元素:
HTML 範例:
按左上檔案的加號,建立一個名為 index
的 html 檔案
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Hello, World!</h1>
<p>用 Google Apps Script 部署網頁好簡單~</p>
</body>
</html>
Apps Script 後端程式碼:
建立一個 gs 檔案,輸入以下程式碼:
function doGet() {
// 載入並返回 HTML 頁面
return HtmlService.createHtmlOutputFromFile('index'); // index 為網頁 html 名稱
}
Note:GAS 網頁部署跟 github 有點類似,並不會每分每秒立馬同步程式碼
如果有修改程式碼,需要即時看其所造成的網頁效果,可點擊「測試部署作業」> 複製「網頁應用程式」的網址連結至網址列,重新整理此連結便可瀏覽最新修改情形!
沒錯,這樣你就能獲得一個超簡樸的 Hello World 網頁~
但這樣太無聊~竟然都連結 Google Sheet 了
我們就來用 Google sheet 儲存資料,利用 GAS 來做CRUD 並幫我們呈現成網頁吧!
Task
(任務)Due Date
(截止日期)Creation Date
(新增日期)你的 Google Sheets 應該如下:
Task | Due Date | Creation Date |
---|---|---|
Task 1 | 2024-10-10 | 2024-10-03 |
按左上角檔案的「+」號,新增一個 HTML 檔案,命名為 index,並輸入以下程式碼:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>To-Do List</h1>
<input type="text" id="taskInput" placeholder="輸入任務">
<input type="date" id="dueDateInput" placeholder="到期日">
<button onclick="addTask()">新增任務</button>
<table id="taskTable">
<thead>
<tr>
<th>任務</th>
<th>截止日期</th>
<th>新增日期</th>
<th>操作</th>
</tr>
</thead>
<tbody id="taskBody">
<!-- 任務清單會被 JavaScript 動態新增到這裡 -->
</tbody>
</table>
<script>
function loadTasks() {
google.script.run.withSuccessHandler(function(tasks) {
var taskTable = document.getElementById('taskTable');
var taskBody = document.getElementById('taskBody');
taskBody.innerHTML = ''; // 清空表格內容
if (tasks.length > 0) {
tasks.forEach(function(task) {
var row = document.createElement('tr');
var taskCell = document.createElement('td'); // 任務單元格
var dueDateCell = document.createElement('td'); // 截止日期單元格
var creationDateCell = document.createElement('td'); // 新增日期單元格
var deleteCell = document.createElement('td'); // 刪除按鈕單元格
taskCell.textContent = task.task; // 設定任務內容
dueDateCell.textContent = task.dueDate; // 設定截止日期
creationDateCell.textContent = task.creationDate; // 設定新增日期
// 創建刪除按鈕
var deleteBtn = document.createElement('button');
deleteBtn.textContent = '刪除';
deleteBtn.className = 'delete-btn';
deleteBtn.onclick = function() {
deleteTask(task.task);
};
deleteCell.appendChild(deleteBtn); // 將刪除按鈕新增到單元格
row.appendChild(taskCell); // 將任務單元格新增到行
row.appendChild(dueDateCell); // 將截止日期單元格新增到行
row.appendChild(creationDateCell); // 將新增日期單元格新增到行
row.appendChild(deleteCell); // 將刪除按鈕單元格新增到行
taskBody.appendChild(row); // 將整行新增到表格主體中
});
} else {
console.log('沒有找到任務');
}
}).getTasks(); // 呼叫 GAS 後端函數取得任務
}
// 新增任務
function addTask() {
var task = document.getElementById('taskInput').value;
var dueDate = document.getElementById('dueDateInput').value;
if (task && dueDate) {
google.script.run.withSuccessHandler(loadTasks).addTask(task, dueDate); // 新增後重新載入任務列表
document.getElementById('taskInput').value = ''; // 清空輸入框
document.getElementById('dueDateInput').value = ''; // 清空日期框
} else {
alert('請輸入任務和截止日期');
}
}
// 刪除任務
function deleteTask(task) {
google.script.run.withSuccessHandler(loadTasks).deleteTask(task); // 刪除後重新載入任務列表
}
// 當頁面載入完成後,自動載入任務
window.onload = loadTasks;
</script>
</body>
</html>
google.script.run.withSuccessHandler(loadTasks).addTask(task, dueDate);
意思是會等後端 GAS addTask() 成功後,再執行 js loadTask 的 function.// 取得 Google 試算表
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('{你的工作表名稱}');;
// 返回 HTML 頁面
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
// 從 Google Sheets 中取得所有任務
function getTasks() {
var data = sheet.getRange(2, 1, sheet.getLastRow() - 1, 3).getValues(); // 讀取所有行的三列數據
var tasks = [];
for (var i = 0; i < data.length; i++) {
var row = data[i];
tasks.push({
task: row[0],
dueDate: row[1].toISOString().split('T')[0],
creationDate: row[2].toISOString().split('T')[0]
});
}
return tasks;
}
// 新增任務,並包含到期日與創建日
function addTask(task, dueDate) {
var creationDate = new Date(); // 自動生成新增日期
sheet.appendRow([task, dueDate, creationDate]); // 將新任務、截止日期和新增日期寫入試算表
}
// 刪除任務
function deleteTask(task) {
var range = sheet.getDataRange(); // 取得所有資料範圍
var values = range.getValues();
for (var i = 1; i < values.length; i++) {
if (values[i][0] == task) {
sheet.deleteRow(i + 1); // 刪除對應列
break;
}
}
}
getTasks
取得所有任務資料,注意!從 google sheet 讀取回來的資料格式為 Date Obj, 需把它轉型為 string 再傳回前端顯示!addTask()
接收來自前端資料,並將其儲存到 Google 試算表中。deleteTask()
接收來自前端的命令,並這列資料從 Google 試算表中刪除。查看網頁就會得到像這樣的畫面:
建立幾個簡單的任務清單後的畫面:
目前只有單純的 html,顯示起來相對單調,讓我們加入一些 css 語法讓他變得好看吧!
更新 html 檔:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 20px;
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
th, td {
padding: 12px;
text-align: left;
border: 1px solid #ddd;
}
th {
background-color: #4CAF50; /* 標題行顏色 */
color: white;
}
tr:nth-child(even) {
background-color: #f2f2f2; /* 偶數行顏色 */
}
tr:hover {
background-color: #ddd; /* 滑鼠懸停效果 */
}
caption {
margin: 10px;
font-size: 1.5em;
font-weight: bold;
color: #333;
}
</style>
</head>
<body>
<h1>To-Do List</h1>
<input type="text" id="taskInput" placeholder="輸入任務">
<input type="date" id="dueDateInput" placeholder="到期日">
<button onclick="addTask()">新增任務</button>
<table id="taskTable">
<thead>
<tr>
<th>任務</th>
<th>截止日期</th>
<th>新增日期</th>
<th>操作</th>
</tr>
</thead>
<tbody id="taskBody">
<!-- 任務清單會被 JavaScript 動態新增到這裡 -->
</tbody>
</table>
<script>
function loadTasks() {
google.script.run.withSuccessHandler(function(tasks) {
var taskTable = document.getElementById('taskTable');
var taskBody = document.getElementById('taskBody');
taskBody.innerHTML = ''; // 清空表格內容
if (tasks.length > 0) {
tasks.forEach(function(task) {
var row = document.createElement('tr');
var taskCell = document.createElement('td'); // 任務單元格
var dueDateCell = document.createElement('td'); // 截止日期單元格
var creationDateCell = document.createElement('td'); // 新增日期單元格
var deleteCell = document.createElement('td'); // 刪除按鈕單元格
taskCell.textContent = task.task; // 設定任務內容
dueDateCell.textContent = task.dueDate; // 設定截止日期
creationDateCell.textContent = task.creationDate; // 設定新增日期
// 創建刪除按鈕
var deleteBtn = document.createElement('button');
deleteBtn.textContent = '刪除';
deleteBtn.className = 'delete-btn';
deleteBtn.onclick = function() {
deleteTask(task.task);
};
deleteCell.appendChild(deleteBtn); // 將刪除按鈕新增到單元格
row.appendChild(taskCell); // 將任務單元格新增到行
row.appendChild(dueDateCell); // 將截止日期單元格新增到行
row.appendChild(creationDateCell); // 將新增日期單元格新增到行
row.appendChild(deleteCell); // 將刪除按鈕單元格新增到行
taskBody.appendChild(row); // 將整行新增到表格主體中
});
} else {
console.log('沒有找到任務');
}
}).getTasks(); // 呼叫 GAS 後端函數取得任務
}
// 新增任務
function addTask() {
var task = document.getElementById('taskInput').value;
var dueDate = document.getElementById('dueDateInput').value;
if (task && dueDate) {
google.script.run.withSuccessHandler(loadTasks).addTask(task, dueDate); // 新增後重新載入任務列表
document.getElementById('taskInput').value = ''; // 清空輸入框
document.getElementById('dueDateInput').value = ''; // 清空日期框
} else {
alert('請輸入任務和截止日期');
}
}
// 刪除任務
function deleteTask(task) {
google.script.run.withSuccessHandler(loadTasks).deleteTask(task); // 刪除後重新載入任務列表
}
// 當頁面載入完成後,自動載入任務
window.onload = loadTasks;
</script>
</body>
</html>
Note: GAS 並不是專門為了網頁所設計,所以只能支援最單純的 css 語法,且只能加入至 html 檔案當中,沒辦法另外建立 css file 唷~
網頁呈現:
而背後 Google Sheet 的資料對應如下:
這樣就建立好一個 To-Do List 的網頁啦 🚀🚀🚀
你可以透過網頁做增刪改減,也可以透過 google sheet 管理資料!
如此你就學會如何用 GAS 部署網站啦~
快依照這個範例做出類似的應用,漂亮的顯示你想呈現的資料吧!